#ifndef __T_AT_H__
#define __T_AT_H__
#include "t_platform.h"
#include "t_at_port.h"
#include "t_at_ringbuffer.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
 * @brief 自动添加CRLF的AT命令格式化宏
 * @note 在使用时，确保输出缓冲区足够大以容纳格式化后的字符串
 */
#define AT_CMD_FORMAT_AUTO_CRLF(output, out_size, out_len, fmt, ...) \
    do { \
        if (sizeof((const char*[]){#__VA_ARGS__}) == 1 && #__VA_ARGS__[0] == '\0') { \
            AT_CMD_FORMAT((output), (out_size), (out_len), "%s\r\n", (fmt)); \
        } else { \
            AT_CMD_FORMAT((output), (out_size), (out_len), fmt "\r\n", ##__VA_ARGS__); \
        } \
    } while(0)
				
#ifndef _T_AT_DEBUG
#if T_AT_DEBUG_EN
#define AT_DEBUG(fmt, args...) printf(fmt, ##args)
#else
#define AT_DEBUG(fmt, args...) \
    do                         \
    {                          \
    } while (0)
#endif
#endif

#ifndef _T_AT_RTOS
#if T_AT_RTOS_EN
#include "FreeRTOS.h"
#include "event_groups.h"

#else
#define AT_MALLOC malloc
#define AT_FREE free
#endif
#endif

    typedef enum
    {
        T_OS_ERROR = -1,
        T_OS_OK,
        T_OS_TIMOUT,
    } T_OSLokType;

    typedef enum
    {
        AT_ERROR = -1,
        AT_OK = 0,
        AT_TIMEOUT,
        AT_RESEND_TIMEOUT,
        /*FUNC*/
        FUN_Err,
        FUN_OK,
        /*urc*/
        URC_FIND,
        URC_NOT_FIND,
    } T_ErrType;

    typedef rbuf_err_t (*t_at_rbuf_init)(rbuf *rbuf_t);
    typedef rbuf_err_t (*t_at_rbuf_push)(rbuf *rbuf_t, rdata_buff *rdata_buff_t);
    typedef rbuf_err_t (*t_at_rbuf_pop)(rbuf *rbuf_t, rdata_buff *rdata_buff_t);
    typedef rbuf_err_t (*t_at_rbuf_clear)(rbuf *rbuf_t);
    typedef rbuf_err_t (*t_at_rbuf_is_empty)(rbuf *rbuf_t);
    typedef rbuf_err_t (*t_at_rbuf_is_full)(rbuf *rbuf_t);

    typedef T_OSLokType (*t_at_os_init)(void *os);
    typedef T_OSLokType (*t_at_os_lock)(void *os, uint32_t locktime); // lock
    typedef T_OSLokType (*t_at_os_unlock)(void *os);                  // unlock

    typedef uint8_t (*t_at_send)(void *Ptx, uint8_t *dataBuf, uint16_t bufLen);
    typedef uint8_t (*t_at_urc_callback)(void *Ptx, uint8_t *dataBuf, uint8_t len, uint8_t *cmd_UrcString);
    typedef uint8_t (*t_at_delay)(uint32_t t_delay_counts);

    typedef struct
    {
        uint8_t rvbuffer[RCV_BUFFER_SIZE];
        uint8_t prabuffer[RCV_BUFFER_SIZE];
        uint8_t ucr_cmd_buffer[URC_CMD_BUFFER_SIZE];
    } at_buffer_t;

    typedef struct
    {
        void *Ptx;                             /*User data1*/
        void *user_arg;                        /*User data2*/
        void *urc_arg;                         /*urc data*/
        uint8_t NubResend;                              /*The number of resends*/
        at_buffer_t *buffer;                            /*AT revbuff*/
        uint32_t attempts_waittime;                     /*AT wait time*/
        uint32_t send_cmds_time;                        /*AT send_cmd_wait time*/
        t_at_delay  at_delay;                            /*AT delay function*/
        t_at_send t_send;                               /*AT send function*/
        t_at_urc_callback urc_handle;                   /*AT URC handle function*/
          
        /*Parsing the shadow space of the data buffer*/ // Handle emergencies eg:++MQTTREV:
        t_at_urc_callback Par_urc_callback;
        /*RTOS*/
        void *os; /*os lock handle*/
        t_at_os_init os_init;
        t_at_os_lock os_lock;
        t_at_os_unlock os_unlock;
        /*ringbuffer for urc's events*/
        rbuf *rbufer;
        rbuf *urc_rbufer;
        t_at_rbuf_init rbuf_init;
        t_at_rbuf_push rbuf_push;
        t_at_rbuf_pop rbuf_pop;
        t_at_rbuf_clear rbuf_clear;
        t_at_rbuf_is_empty rbuf_is_empty;
        t_at_rbuf_is_full rbuf_is_full;
    } t_at_t;

    typedef struct
    {
        uint8_t urc_buffer[URC_CMD_BUFFER_SIZE]; /*AT revbuff*/
        t_at_urc_callback urc_handle;            /*AT URC handle function*/
    } t_at_urc_t;

#if T_AT_RTOS_EN
    T_OSLokType t_at_os_init_t(void *os);

    T_OSLokType t_at_os_lock_t(void *os, uint32_t locktime);

    T_OSLokType t_at_os_unlock_t(void *os);
#endif

    // msater  
    void t_at_destroy(t_at_t *me);
    /*no-os*/
    void t_at_1ms_cycle(void);
    /*create at fw*/
    t_at_t *t_at_create(t_at_send t_send, t_at_urc_callback urc_handle, uint32_t attempts_waittime, uint8_t NubResend); // Create AT object
    //add
	T_ErrType t_at_delay_add(t_at_t *me,t_at_delay delay_t);	
    //add
	T_ErrType t_at_send_add(t_at_t *me, t_at_send hw_send);
    //add
    T_ErrType t_at_os_add(t_at_t *me, void *os, t_at_os_init os_init, t_at_os_lock os_lock, t_at_os_unlock os_unlock); // OS init
    //add
    T_ErrType t_at_ringbuffer_add(t_at_t *me,
                                     rbuf *rbufer,
                                     t_at_rbuf_init rbf_init_F,
                                     t_at_rbuf_push rbf_push_F,
                                     t_at_rbuf_pop rbf_pop_F,
                                     t_at_rbuf_clear rbf_clear_F,
                                     t_at_rbuf_is_empty rbf_is_empty_F,
                                     t_at_rbuf_is_full rbf_is_full_F); // buffer API init
    //挂载URC对象                                 
    void t_at_urc_ringbuffer_add(t_at_t *me, rbuf *urc_rbuf);                                  
    //普通
    T_ErrType t_at_rev_push_data(t_at_t *me, uint8_t *buffer, uint16_t len); // revbuff push
    //待循环对列的数据压入
    T_ErrType t_at_rev_push_data_rbf(t_at_t *me, uint8_t *buffer, uint16_t len,char *cmd_UrcString);
   //Send AT command
    T_ErrType t_at_cmd_send(t_at_t *me, //  AT objects
                            uint16_t data_len,// 发送cmd长度
                            char *CMD, //发送cmd数据
                            char *CMD_UCR, //匹配回调的关键字
                            t_at_urc_callback phandle, //匹配成功后 cb函数
                            uint32_t waittime,//发送指令的间隔
                            uint8_t resendCount//错误重新发送的次数
                           ); 
                           
    // Parsing the shadow space of the data buffer
    T_ErrType t_at_urc_callback_set(t_at_t *me, t_at_urc_callback urc_callback);
    //设置发送间隔时间
    T_ErrType t_at_send_time_set(t_at_t *me, uint32_t sp_time); // Set the time to send the command
   
    T_ErrType t_at_parse_polling(t_at_t *me, uint8_t *URC);

    T_ErrType t_at_parse_polling_rbf(t_at_t *me, uint8_t *URC);

    T_ErrType t_at_set_URC_userarg(t_at_t *me, void *urc_arg);

    uint16_t AT_CMD_FORMAT(char *output, uint16_t out_size, uint16_t *out_len, const char *fmt, ...);

#ifdef __cplusplus
}
#endif

#endif
/*__T_AT_H__*/
